package com.accounting.client.frontend.system;

import java.util.List;

import com.accounting.client.remote.Services;
import com.accounting.client.remote.enumeration.TimeSpans;
import com.accounting.client.remote.obj.Product;
import com.accounting.client.remote.obj.Statistic;
import com.accounting.client.remote.transfer.StatisticRequest;
import com.accounting.client.session.ErrorHandler;
import com.accounting.client.session.SessionManager;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Widget;

import corelib.client.CollectionUtil;
import corelib.client.NumberFormats;
import corelib.client.Util;
import corelib.client.resource.CommonResources;
import corelib.client.schedule.DeferredTask;
import corelib.client.search.PagingRequest;
import corelib.client.search.PagingResult;
import corelib.client.ui.SimpleMask;
import corelib.client.ui.widget.SimpleDataModel;
import corelib.client.ui.widget.WidgetListener;
import corelib.client.ui.widget.button.Button;
import corelib.client.ui.widget.dialog.SimpleLargeDialogHandler;
import corelib.client.ui.widget.form.DateBox;
import corelib.client.ui.widget.form.SelectField;
import corelib.client.ui.widget.form.SimpleLabel;
import corelib.client.ui.widget.form.fomatters.ValueFormatter;
import corelib.client.ui.widget.grid.SimpleDataGrid;
import corelib.client.ui.widget.grid.SimpleDataGridHandler;
import corelib.client.ui.widget.grid.cell.CellRenderer;
import corelib.client.ui.widget.grid.column.ColumnConfig;
import corelib.client.ui.widget.grid.column.ColumnConfigs;
import corelib.client.ui.widget.layout.RelativeRow;
import corelib.client.ui.widget.panel.SimpleLayoutPanel;
import corelib.client.ui.widget.toolbar.SimpleRibbon;

public class StatisticHandler extends SimpleLargeDialogHandler {
	
	private SimpleRibbon ribbon;
	private SimpleDataGrid<Statistic> statisticTable;
	private StatisticTableHandler statisticTableHandler;
	private SelectField<TimeSpans>  timeSpanField;
	private SelectField<Product>    productField;
	
	private DateBox dateForm;
	private DateBox dateTo;
	
	@Override
	public Widget getContentPanel() {
		ribbon = createRibbon();
		statisticTable = createTable();
		
		SimpleLayoutPanel layout = new SimpleLayoutPanel();
		layout.add(ribbon);
		layout.add(statisticTable);
		layout.setWidgetTopHeight(ribbon, 0, Unit.PX, 50, Unit.PX);
		layout.setWidgetTopBottom(statisticTable, 50, Unit.PX, 0, Unit.PX);
		
		return layout;
	}
	
	protected SimpleRibbon createRibbon() {
		WidgetListener listener = new WidgetListener(){
			@Override
			public void valueUpdated(Widget widget) {
				if (timeSpanField.getSelectedOption() != null){
					dateForm.reset();
					dateTo.reset();
					dateForm.setEnabled(false);
					dateTo.setEnabled(false);
				}
				else {
					dateForm.setEnabled(true);
					dateTo.setEnabled(true);
				}
				load();
			}
		};
		
		SimpleRibbon ribbon = new SimpleRibbon();
		productField  = new SelectField<Product>(listener);
		productField.setNullable(true);
		productField.setOptionFormatter("请选择产品", new ValueFormatter<Product>(){
			@Override
			public String format(Product value) {
				return value.getCName();
			}
		});
		
		timeSpanField = new SelectField<TimeSpans>(TimeSpans.All, listener);
		timeSpanField.setNullable(true);
		timeSpanField.setOptionFormatter("所有记录统计数据", new ValueFormatter<TimeSpans>(){
			@Override
			public String format(TimeSpans value) {
				return value.getName() + "统计数据";
			}
		});
		
		RelativeRow row = new RelativeRow();
		row.add(productField, 250)
		   .addSpace(12);
		
		row.add(timeSpanField, 150)
		   .addSpace(12);
		
		row.add(new SimpleLabel("From :").setBold(true))
		   .addSpace(12)
		   .add(dateForm = new DateBox(listener),150)
		   .addSpace(12)
		   .add(new SimpleLabel("To :").setBold(true))
		   .addSpace(12)
		   .add(dateTo = new DateBox(listener),150)
		   .addSpace(12)
		   .add(new Button("Search", CommonResources.INSTANCE.refresh(), new WidgetListener(){
				@Override
				public void valueUpdated(Widget widget) {
					load();
				}
		   }))
		   .addSpace(12)
		   .add(new Button("Reset",new WidgetListener(){
				@Override
				public void valueUpdated(Widget widget) {
					reset();
					load();
				}
		   }));
		
		row.getPanel().getElement().getStyle().setMarginTop(5, Unit.PX);
		ribbon.addWidget(row.getPanel());
		ribbon.addWidget(new Button("Close", CommonResources.INSTANCE.exit20(),
				new WidgetListener(){
					@Override
					public void valueUpdated(Widget widget) {
						closeDialog();
					}
				}
		),Style.Float.RIGHT);
		
		dateForm.reset();
		dateTo.reset();
		return ribbon;
	}
	
	@Override
	public void onShowing() {
		super.onShowing();
		new DeferredTask().run(new ScheduledCommand(){
			@Override
			public void execute() {
				load();
				loadProducts();
			}
		}, 400);
	}
	
	private void reset(){
		dateTo.reset();
		dateForm.reset();
		productField.setSelectedOption(null);
		timeSpanField.setSelectedOption(null);
	}
	
	private void loadProducts(){
		PagingRequest request = new PagingRequest();
		request.setOffset(0);
		request.setLimit(100);
		request.setKeyword(Util.EMPTY_STRING);
		
		Services.ProductService.ListProductsByKeyword(SessionManager.getPassport(), request,
			new AsyncCallback<PagingResult<Product>>(){
				@Override
				public void onFailure(Throwable caught) {
					ErrorHandler.handleServiceError(caught);
				}
				
				@Override
				public void onSuccess(PagingResult<Product> result) {
					productField.setOptions(result.getData(), false);
				}
			}
		);
	}
	
	private void load() {
		StatisticRequest request = new StatisticRequest();
		request.setFrom(dateForm.getDate());
		request.setTo(dateTo.getDate());
		request.setProductId(productField.getSelectedOption() == null ? null: productField.getSelectedOption().getProductId());
		
		if (timeSpanField.getSelectedOption() != null) {
			if (timeSpanField.getSelectedOption().getType() == TimeSpans.CURRENT_MONTH.getType()){
				request.setCurrentMonth(true);
				request.setCurrentYear(null);
				request.setFrom(null);
				request.setTo(null);
			}
			if (timeSpanField.getSelectedOption().getType() == TimeSpans.CURRENT_YEAR.getType()){
				request.setCurrentYear(true);
				request.setCurrentMonth(null);
				request.setFrom(null);
				request.setTo(null);
			}
		}
		
		SimpleMask.mask(statisticTable, "Loading...");
		Services.ReportService.GetStatistics(SessionManager.getPassport(), request, new AsyncCallback<List<Statistic>>(){
			@Override
			public void onFailure(Throwable caught) {
				SimpleMask.hide(statisticTable);
				ErrorHandler.handleServiceError(caught);
			}
			
			@Override
			public void onSuccess(List<Statistic> result) {
				SimpleMask.hide(statisticTable);
				statisticTableHandler.setObjects(result);
			}
		});
	}
	
	protected SimpleDataGrid<Statistic> createTable() {
		return new SimpleDataGrid<Statistic>(1000, 
			   statisticTableHandler = new StatisticTableHandler()
		);
	}
	
	private class PurchaseNumberCellRender extends CellRenderer<Statistic> {
		@Override
		public void render(SimpleDataModel<Statistic> model,
				ColumnConfig columnConfig, int rowIndex, int colIndex,
				SafeHtmlBuilder sb) {
			Statistic state = model.getObject();
			sb.append(SimpleLabel.createPrimary(""+state.getTotalNumberOfPurchases()).asSafeHtml());
		}
	}
	
	private class SalesNumberCellRender extends CellRenderer<Statistic> {
		@Override
		public void render(SimpleDataModel<Statistic> model,
						   ColumnConfig columnConfig, int rowIndex, int colIndex,
						   SafeHtmlBuilder sb) {
			Statistic state = model.getObject();
			sb.append(SimpleLabel.createSuccess(""+state.getTotalNumberOfOrders()).asSafeHtml());
		}
	}
	
	private class StockNumberCellRender extends CellRenderer<Statistic> {
		@Override
		public void render(SimpleDataModel<Statistic> model,
						   ColumnConfig columnConfig, int rowIndex, int colIndex,
						   SafeHtmlBuilder sb) {
			Statistic state = model.getObject();
			int stock = state.getTotalNumberOfPurchases() - state.getTotalNumberOfOrders();
			sb.append(SimpleLabel.createInfo(Util.EMPTY_STRING + stock).asSafeHtml());
		}
	}
	
	private class StatisticTableHandler extends SimpleDataGridHandler<Statistic> {
		
		private final static String Name 		    = "Name";
		private final static String PurchasePrice   = "PurchasePrice";
		private final static String PurchaseNumber  = "PurchaseNumber";
		private final static String SalesPrice      = "SalesPrice";
		private final static String SalesNumber     = "SalesNumber";
		private final static String StockNumber     = "StockNumber";
		private final static String PurchasePostage = "PurchasePostage";
		private final static String OrderPostage    = "OrderPostage";
		
		private List<Statistic> data;
		
		@Override
		public List<ColumnConfig> createColumns() {
			List<ColumnConfig> configs = CollectionUtil.newArrayList();
			configs.add(ColumnConfigs.create(Name, 			 "产品名称",    100));
			configs.add(ColumnConfigs.create(PurchasePrice,  "总购买成本",   100, NumberFormats.AUD));
			configs.add(ColumnConfigs.create(PurchasePostage,"总入库邮费",   100, NumberFormats.AUD));
			configs.add(ColumnConfigs.create(PurchaseNumber, "购买量",   50,  new PurchaseNumberCellRender()));
			configs.add(ColumnConfigs.create(SalesNumber,    "销量",   50,  new SalesNumberCellRender()));
			configs.add(ColumnConfigs.create(StockNumber,    "库存",      50,  new StockNumberCellRender()));
			configs.add(ColumnConfigs.create(OrderPostage,   "总销售订单邮费", 100,  NumberFormats.AUD));
			configs.add(ColumnConfigs.create(SalesPrice,     "总销售价格",   100,   NumberFormats.RMB));
			
			return configs;
		}
 
		@Override
		public void format(int index, SimpleDataModel<Statistic> model) {
			Statistic state = model.getObject();
			model.set(Name, 		    state.getProductName());
			model.set(PurchasePrice,    state.getPurchasePrice());
			model.set(PurchasePostage,  state.getPostage());
			model.set(PurchaseNumber,   state.getTotalNumberOfPurchases());
			model.set(SalesPrice,       state.getOrderPrice());
			model.set(OrderPostage,     state.getOrderPostage());
			model.set(SalesNumber,      state.getTotalNumberOfOrders());
		}
		
		public void setObjects(List<Statistic> objects){
			data = objects;
			getGrid().setObjects(objects);
		}
		
		@Override
		public List<Statistic> getObjects() {
			return data;
		}

		@Override
		public void onObjectClicked(Statistic obj) {}

		@Override
		public void onObjectDoubleClicked(Statistic obj) {}
		
	}
	
	
	
}
